package model;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.*;

/**
 * Classe representant le serveur d'ecoute UDP
 * @author Lefevre, Thoue
 */
public class RecepteurUDP extends Thread {

    private boolean running;
    private Manager manager;
    final static int taille = 640;
    static byte buff[] = new byte[taille];
    SourceDataLine line = null;
    AudioInputStream audioInputStream = null;
    AudioFormat audioFormat = null;

    /**
     * Constructeur
     * @param manager lien vers le manager des threads
     */
    public RecepteurUDP(Manager manager) {
        running = true;
        this.manager = manager;
    }

    /**
     * Methode principal du thread -
     * Recois le son sous forme de paquets UDP et le diffuse sur les enceintes.
     */
    @Override
    public void run() {
        DatagramSocket socketUDP = null;
        Logger.getLogger(RecepteurUDP.class.getName()).log(Level.INFO, "Ecoute UDP demarrer.");
        try {
            socketUDP = new DatagramSocket(2013);
            DatagramPacket donneesRecues = new DatagramPacket(buff, taille);
            while (running) {
                //configuration du son
                audioFormat = new AudioFormat(manager.getModel().getSampleRate(), manager.getModel().getSampleSizeInBits(), manager.getModel().getChannels(), manager.getModel().isSigned(), manager.getModel().isBigEndian());
                DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
                line = (SourceDataLine) AudioSystem.getLine(info);
                line.open(audioFormat);
                while (running) {
                    socketUDP.receive(donneesRecues); //reception d'un paquet udp
                    for (Iterator it = manager.getServeur().getConversations().iterator(); it.hasNext();) {
                        Conversation convers = (Conversation) it.next();
                        if (convers.getStatus() == EStatusConversation.ETABLISH) {
                            if (convers.getUser().getIp().equals(donneesRecues.getAddress().getHostAddress()) //si la conversation est dans la liste
                                    && !convers.isMute()) { //si la conversation n'est pas mute
                                line.start();                                
                                line.write(donneesRecues.getData(), 0, donneesRecues.getLength()); //diffusion sur les enceintes
                                line.stop();
                            }
                        }
                    }
                }
                line.drain();
                line.close();
            }
            socketUDP.close();
        } catch (SocketException ex) {
            Logger.getLogger(RecepteurUDP.class.getName()).log(Level.INFO, "La socket UDP a ete ferme.");
        } catch (IOException ex) {
            Logger.getLogger(RecepteurUDP.class.getName()).log(Level.SEVERE, null, ex);
        } catch (LineUnavailableException ex) {
            Logger.getLogger(RecepteurUDP.class.getName()).log(Level.INFO,"Aucune enceinte detecte");
        }
    }
}
